from django.test import TestCase
from django.db.models import Q
from skillchallenge.models import *
from skillchallenge.game import *
         
class LocationEngineTestCase(TestCase):
    
    target = None
    
    def setUp(self):
        self.target = LocationEngine()
        Tick.objects.create(tick = 1)
    
    def test_create_location(self):
        name = 'location 1'
        desc = 'test description'
        self.target.create_location(name=name, description=desc)
        
        self.assertTrue(Location.objects.count() == 1)
        
        l = Location.objects.get(id=1)
        
        self.assertTrue(l.name == name)
        self.assertTrue(l.description == desc)
        self.assertTrue(l.initial == False)
        
    def test_initial_location(self):
        
        l1 = self.target.create_location(name = 'location 1',
                                         description = 'test description', 
                                         initial=True)
        
        e = Event.objects.filter(info__istartswith = self.target.INITIAL_MOVE)[0]
        self.assertTrue(e.scheduled == False)
        self.assertTrue(e.schedule_start == None and e.schedule_end == None)
        self.assertTrue(e.player_will == True)
        self.assertTrue(e.recurring == False)
        self.assertTrue(e.timestamp == None)
        
        codeng = CodeEngine()
        
        self.assertTrue(e.preconditions.count() == 1)
        p1 = e.preconditions.all()[0]
        self.assertTrue(codeng.assert_is_negate_by_info(p1, self.target.INITIAL_MOVE))
        
        self.assertTrue(e.actions.count() == 2)
        m1 = e.actions.all()[0]
        m2 = e.actions.all()[1]
        self.assertTrue(codeng.assert_is_message(m1, 
                                                 'you arrived in ' + l1.name + '.' ))
        self.assertTrue(codeng.assert_is_message(m2, 
                                                 'you see: ' + l1.description + '.' ))
    
    def test_get_initial_moves(self):
        l = self.target.initial_moves()
        self.assertTrue(len(l) == 0)
        
        self.target.create_location(name = 'location 1',
                                    description = 'test description', 
                                    initial=True)
        
        self.target.create_location(name = 'location 2',
                                    description = 'test description 2', 
                                    initial=True)
        
        self.target.create_location(name = 'location 3',
                                    description = 'test description', 
                                    initial=False)
        
        l = self.target.initial_moves()
        self.assertTrue(len(l) == 2)
        
    def test_created_stay_event(self):
        l1 = self.target.create_location(name = 'location 1',
                                    description = 'test description', 
                                    initial=True)
        e = Event.objects.filter(info__istartswith = self.target.STAY)[0]
        
        self.assertTrue(e.scheduled == False)
        self.assertTrue(e.schedule_start == None and e.schedule_end == None)
        self.assertTrue(e.player_will == False)
        self.assertTrue(e.recurring == True)
        self.assertTrue(e.timestamp == None)
        
        self.assertTrue(e.actions.count() == 1)    
        
        action = e.actions.all()[0]
        
        codeng = CodeEngine()
        
        self.assertTrue(codeng.assert_is_message(action, 
                                                 'you stayed in ' + l1.name + '.' ))  
        
        self.assertTrue(e.preconditions.all()[0] == self.target.__is_in_query__(l1))
        
    def test_create_path(self):
        "when create a path, a path is created"
        l1 = Location.objects.create(name='location 1')
        l2 = Location.objects.create(name='location 2')
        LocationEngine().create_path(l1, l2)
        
        e = Event.objects.filter(info__istartswith = self.target.MOVE)[0]
        
        self.assertTrue(e.scheduled == False)
        self.assertTrue(e.schedule_start == None and e.schedule_end == None)
        self.assertTrue(e.player_will == True)
        self.assertTrue(e.recurring == True)
        self.assertTrue(e.timestamp == None)
        self.assertTrue(e.online == True)
        
        self.assertTrue(e.actions.count() == 2)    
        
        m1 = e.actions.all()[0]
        m2 = e.actions.all()[1]
        
        codeng = CodeEngine()
        
        self.assertTrue(codeng.assert_is_message(m1, 
                                                 'you arrived in ' + l2.name + '.' ))
        self.assertTrue(codeng.assert_is_message(m2, 
                                                 'you see: ' + l2.description + '.' ))
        
        self.assertTrue(e.preconditions.count() == 1)
        self.assertTrue(e.preconditions.all()[0] == self.target.__is_in_query__(l1))
    
    def test_is_in_query(self):
        location = Location(name='test')
        stay = 'Q(info__istartswith="' + self.target.STAY + '")'
        moving = 'Q(info__istartswith="' + self.target.MOVE + '")'
        initial_moving = 'Q(info__istartswith="' + self.target.INITIAL_MOVE + '")'
        is_in = 'query = (' + stay + ' | ' + moving + ' | ' + initial_moving + ')&Q(timestamp__tick = now.tick)'
        
        self.assertEquals(is_in, self.target.__is_in_query__(location).code_array[0])
        globals()['now'] = Tick.objects.latest()
        exec(is_in)
        
        here = 'query = Q(info__iendswith="'+str(location.id)+ '")'
        self.assertEquals(here, self.target.__is_in_query__(location).code_array[5])
        
        
